/*
Matthew Parker
CPE 301 Design Assignment 3
4/1/2014
1. Use the output of timer1 to drive timer0 as an external clock
2. Output timer0 to port B
3. Ignore timer0 overflow, and use an interrupt for timer1 delay instead of polling
4. The output PC0 is toggled every 16 falling edge from timer1, and is caught using an interrupt
*/


#include <avr/io.h>
#include <avr/interrupt.h>

int main(void)
{
    DDRB = 0xFF; //output of timer0
	DDRC = 0x01; //output that is toggled every 16th falling edge of timer1
	DDRD = 0x00;
	
	TCCR0B = 0x06; //CS = 110 for external clock, falling edge
	//CTC Mode, prescalar of 1024
	TCCR1B = (1 << WGM12)|(1 << CS12)|(1 << CS10);
	OCR1A = 0xF42; //50% duty cycle and 1 sec period
	TIMSK1 = (1 << OCIE1A); //Enable interrupt when compare match on OCR1A
	EICRA = (1 << ISC11); //Enable int0 interrupt any time it changes
	sei(); //Enable global interrupts
	TCNT1 = 0;
	while (1){
		//Wait for Timer1 to match OCR1A
		//DEBUG:
		/*
		if (TCNT1 <= 0xF30){
			TCNT1 = 0XF40;
		} else {
			TCNT1++;
		}
		*/
	}

	return 0;
}


ISR (TIMER1_COMPA_vect){
	//Called every falling edge of the output from timer1 (TCNT1 == OCR1A)
	sei(); //Enables interrupt for when int0 is toggled
	PORTD ^= 0x12; //Toggle T0 and int0 (PD4 and PD2)
}

ISR (INT0_vect){
	//Called every time INT0 is toggled, which happens every falling edge from timer1's output
	PORTB = TCNT0;
	if(TCNT1 % 16 == 0)
		PORTC ^= 0x01; //Toggle PC0
}
